#!/usr/bin/env python3
# -*- coding: utf-8 -*-
u"""
如何通过Flask和Peewee开启一个简易api

以蓝图的形式，将各个不同的功能模块化，便于管理与修改
"""
import re
from flask import Blueprint
from flask import jsonify
from flask import request
try:
    from src.db.sqliteDB import EnhancerTable
    from src.lib.FlaskDatablesAgent import FlaskDataTablesAgent
    from src.lib.fuzzyfinder import fuzzyfinder
except ImportError:
    try:
        from db.sqliteDB import EnhancerTable
        from lib.FlaskDatablesAgent import FlaskDataTablesAgent
        from lib.fuzzyfinder import fuzzyfinder
    except ImportError:
        from sqliteDB import EnhancerTable
        from FlaskDatablesAgent import FlaskDataTablesAgent
        from fuzzyfinder import fuzzyfinder


__author__ = "张一鸣"
__date__ = "2018.3.22"
__version__ = 0.1


# 新建一个blueprint
api = Blueprint("api", __name__, "templates")

# 配合Flask的request返回参数


def get_parameter(label, default=None):
    u"""
    request.args.get获取的字符串结果，可能环绕有各种空白字符等，需要记性strip
    """
    tem = request.args.get(label)

    if tem is None:
        return default
    return tem.strip()


# 一个正则匹配，解析chr1:100-1000形式的位点
def get_position(position):
    u"""
    2017.11.21 解析位点信息的
    :param position: eg: chr1:100-1000
    :return: {chrom: 'chr1', start: 100, end: 1000}
    """
    pattern = r"^(?P<chrom>chr\w+):(?P<start>\d+)-(?P<end>\d+)"

    position = re.search(pattern, position)

    if position:
        return position.groupdict()
    return None


# 自动填写的api
@api.route("/autocomplete")
def autocomplete():
    u"""
    通常数据库查询或者百度谷歌搜索，会有一个自动补全的功能，
    这就是提供自动补全选项的api
    此处仅做示例，功能简单，
    如有需要请自行添加其他参数等

    ！该功能，需要相应的JS代码配合！
    :return: None
    """
    pattern = get_parameter("q")

    table = EnhancerTable
    column = [
        EnhancerTable.tissue, EnhancerTable.enhancerID
    ]

    # 输入的是染色体位点的话，不费精力去查询
    if re.search(r"^chr(\w+)?:?(\d+)?-?(\d+)?", pattern):
        return jsonify(matching_results=[])

    data = []
    '''
    利用好数据库模块本身的正则匹配功能
    通过循环，一次性匹配能够提供补全功能的多个列
    比如此处我们匹配染色体和id两列
    '''
    for i in column:
        querys = table.select(
            i
        ).where(
            i.regexp(pattern)
        ).distinct().paginate(1, 10).tuples()

        tmp = [x[0] for x in querys]

        '''
        一次提供10个补全选项足以
        '''
        if len(tmp) >= 10:
            data += tmp[0:10]
            break
        data += tmp

    '''
    若没有一个符合规则的，就返回没有结果
    '''
    if len(data) == 0:
        data = ["No results"]

    return jsonify(matching_results=data)


# datatables ajax
@api.route("/ajax")
def ajax():
    u"""
    ajax的表格
    """
    table = EnhancerTable
    column = [
        EnhancerTable.chrom,
        EnhancerTable.start,
        EnhancerTable.end,
        EnhancerTable.enhancerID,
        EnhancerTable.tissue,
        EnhancerTable.id
    ]

    agent = FlaskDataTablesAgent(
        table=table, columns=column, join=None
    )

    # 此处，以组织为例，展示如何通过ajax进行组织的筛选
    tissue = get_parameter("tissue")
    # position
    potition = get_parameter("position")

    condition = None
    if tissue:
        condition = (EnhancerTable.tissue == tissue)

    return jsonify(agent.query(condition=condition))


if __name__ == '__main__':
    querys = EnhancerTable.select(EnhancerTable.tissue).where(
        EnhancerTable.tissue.regexp("dnd")
    ).distinct().dicts()

    for i in querys:
        print(i)
